package com.gift.service.Impl;

import com.gift.dao.AccByDeaMapper;
import com.gift.dao.BankByDealtMapper;
import com.gift.dao.DealTableMapper;
import com.gift.dao.SeTableMapper;
import com.gift.pojo.AccByDea;
import com.gift.pojo.BankByDealt;
import com.gift.pojo.DealTable;
import com.gift.pojo.SeTable;
import com.gift.service.ReportService;
import com.gift.vo.DelAndAccVO;
import com.gift.vo.Table1VO;
import com.gift.vo.Table201VO;
import com.gift.vo.Table3VO;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

@Service("reportService")
public class ReportServiceImpl implements ReportService {

    @Resource
    BankByDealtMapper bankByDealtMapper;
    @Resource
    SeTableMapper seTableMapper;
    @Resource
    DealTableMapper dealTableMapper;


    @Override
    public List getReportVOList1(Map<String,Object> mapO) {
        List<BankByDealt> dealAndBankDLList=bankByDealtMapper.getAllByTime(mapO);
        //根据时间叠合
        Multimap<String, BankByDealt> bankByDealtTMap = ArrayListMultimap.create();
        for(BankByDealt db:dealAndBankDLList){
            LocalDateTime ct =db.getCreatetime();
            int year =ct.getYear();
            int month =ct.getMonthValue();
            int day = ct.getDayOfMonth();
            int whichT = ct.getHour();
            if(0<whichT && whichT<8 || whichT == 0){
                day =day-1;
            }
            String dayT = year +"-"+month+"-"+day;
            bankByDealtTMap.put(dayT,db);
        }
        //现在bankByDealtTMap中key为哪一天，value为一天中所有银行（游戏）list
        Iterator<Map.Entry<String, Collection<BankByDealt>>> it =bankByDealtTMap.asMap().entrySet().iterator();
        List<Table1VO> finaList = new ArrayList<>();
        while (it.hasNext()) {
            List<Table1VO> AccList = new ArrayList<>();
            BigDecimal getAllMoneyEachDay = BigDecimal.ZERO;
            BigDecimal sendAllMoneyEachDay = BigDecimal.ZERO;

            Map.Entry<String, Collection<BankByDealt>> entry = it.next();
            //每一天所有的游戏（银行）的list
            Iterator<BankByDealt> bdList = entry.getValue().iterator();
            //按照银行（游戏）分组
            Multimap<String, BankByDealt> eachDayGBByBidMap = ArrayListMultimap.create();
            while (bdList.hasNext()){
                BankByDealt bbd = bdList.next();
                int bid =bbd.getBid();
                eachDayGBByBidMap.put(Integer.toString(bid),bbd);
            }
            //分组后，迭代每一组合，按照一天中各种银行（游戏）叠加
            Iterator<Map.Entry<String, Collection<BankByDealt>>> ITEachDayGBByBidMap =eachDayGBByBidMap.asMap().entrySet().iterator();
            while (ITEachDayGBByBidMap.hasNext()) {
                Map.Entry<String, Collection<BankByDealt>> bankByDealtListEntry = ITEachDayGBByBidMap.next();
                //得到相同银行（游戏）的list
                Iterator<BankByDealt> bDEnList = bankByDealtListEntry.getValue().iterator();
                //迭代相同银行（游戏）的list。叠加
                Table1VO tv1 =Table1VO.builder().time("").bankCard("").ganmeName("").getMoney(BigDecimal.ZERO).inAllGetMoneyAcc(BigDecimal.ZERO)
                        .sendMoney(BigDecimal.ZERO).poundage(BigDecimal.ZERO).inAllSendMoneyAcc(BigDecimal.ZERO).build();
                tv1.setTime(entry.getKey());
                while (bDEnList.hasNext()){
                    BankByDealt bd = bDEnList.next();
                    tv1.setBankCard(bd.getAlias());
                    tv1.setGanmeName(bd.getGname());
                    tv1.setGetMoney(tv1.getGetMoney().add(bd.getIncome()));
                    tv1.setSendMoney(tv1.getSendMoney().add(bd.getExpend()));
                    tv1.setPoundage(tv1.getPoundage().add(bd.getPoundage()));
                }
                AccList.add(tv1);
            }
            for(Table1VO t1v:AccList){
                getAllMoneyEachDay = getAllMoneyEachDay.add(t1v.getGetMoney());
                sendAllMoneyEachDay = sendAllMoneyEachDay.add(t1v.getSendMoney()).add(t1v.getPoundage());

            }
            //.divide(fundInfoDto.getScale(),2, BigDecimal.ROUND_DOWN)
            for(Table1VO t1v:AccList){
                t1v.setInAllGetMoneyAcc(t1v.getGetMoney().divide(getAllMoneyEachDay,2, BigDecimal.ROUND_DOWN));
                t1v.setInAllSendMoneyAcc(t1v.getSendMoney().add(t1v.getPoundage()).divide(sendAllMoneyEachDay,2, BigDecimal.ROUND_DOWN));
                finaList.add(t1v);
            }

        }

        /**
         * 所有银行流水按照银行（游戏）分组，统计这段时间内，一个银行（游戏）总收钱，
         * 出钱，和在这段时间内的比例
         */
        Multimap<String, BankByDealt> bankByDealtTMap2 = ArrayListMultimap.create();
        for(BankByDealt db:dealAndBankDLList){
            bankByDealtTMap2.put(Integer.toString(db.getBdid()),db);
        }
        Iterator<Map.Entry<String, Collection<BankByDealt>>> it2 =bankByDealtTMap2.asMap().entrySet().iterator();
        List<Table1VO> totalAcc = new ArrayList<>();
        BigDecimal getAllMoney = BigDecimal.ZERO;
        BigDecimal sendAllMoney = BigDecimal.ZERO;
        while (it2.hasNext()) {
            Map.Entry<String, Collection<BankByDealt>> entry = it2.next();
            //每一种游戏（银行）的list
            Iterator<BankByDealt> bdList = entry.getValue().iterator();
            Table1VO tv2 =Table1VO.builder().time("").bankCard("").ganmeName("").getMoney(BigDecimal.ZERO).inAllGetMoneyAcc(BigDecimal.ZERO)
                    .sendMoney(BigDecimal.ZERO).poundage(BigDecimal.ZERO).inAllSendMoneyAcc(BigDecimal.ZERO).build();
            tv2.setTime("总计：");
            while (bdList.hasNext()){
                BankByDealt bbd = bdList.next();
                tv2.setBankCard(bbd.getAlias());
                tv2.setGanmeName(bbd.getGname());
                tv2.setGetMoney(tv2.getGetMoney().add(bbd.getIncome()));
                tv2.setSendMoney(tv2.getSendMoney().add(bbd.getExpend()));
                tv2.setPoundage(tv2.getPoundage().add(bbd.getPoundage()));
            }
            totalAcc.add(tv2);
        }
        for(Table1VO t1v:totalAcc){
            getAllMoney = getAllMoney.add(t1v.getGetMoney());
            sendAllMoney = sendAllMoney.add(t1v.getSendMoney()).add(t1v.getPoundage());

        }
        //.divide(fundInfoDto.getScale(),2, BigDecimal.ROUND_DOWN)
        for(Table1VO t1v:totalAcc){
            t1v.setInAllGetMoneyAcc(t1v.getGetMoney().divide(getAllMoney,2, BigDecimal.ROUND_DOWN));
            t1v.setInAllSendMoneyAcc(t1v.getSendMoney().add(t1v.getPoundage()).divide(sendAllMoney,2, BigDecimal.ROUND_DOWN));
            finaList.add(t1v);
        }

        return finaList;
    }

    @Override
    public List getReportVOList201(Map<String, Object> mapO) {
        List<BankByDealt> dealAndBankDLList=bankByDealtMapper.getAllByTime(mapO);
        //根据时间叠合
        Multimap<String, BankByDealt> bankByDealtTMap = ArrayListMultimap.create();
        for(BankByDealt db:dealAndBankDLList){
            LocalDateTime ct =db.getCreatetime();
            int year =ct.getYear();
            int month =ct.getMonthValue();
            int day = ct.getDayOfMonth();
            int whichT = ct.getHour();
            if(0<whichT && whichT<8 || whichT == 0){
                day =day-1;
            }
            String dayTS = year +"-"+month+"-"+day;
            bankByDealtTMap.put(dayTS,db);
        }
        //现在bankByDealtTMap中key为哪一天，value为一天中所有银行（游戏）list
        Iterator<Map.Entry<String, Collection<BankByDealt>>> it =bankByDealtTMap.asMap().entrySet().iterator();
        List<Table201VO> finaList  = new ArrayList<>();
        while (it.hasNext()) {
            Map.Entry<String, Collection<BankByDealt>> entry = it.next();
            //每一天所有的游戏（银行）的list
            Iterator<BankByDealt> bdList = entry.getValue().iterator();
            Table201VO tv201=Table201VO.builder().time(entry.getKey()).delTpye("普通交易").getMoney(BigDecimal.ZERO).sendMoney(BigDecimal.ZERO)
                    .margin(BigDecimal.ZERO).zaoU("").zhongU("").wanU("").build();
            while (bdList.hasNext()){
                BankByDealt bbd = bdList.next();
                if(bbd.getShift() == 0){
                    tv201.setZaoU(bbd.getHandlers());
                }
                if(bbd.getShift() == 1){
                    tv201.setZhongU(bbd.getHandlers());
                }
                if(bbd.getShift() == 2){
                    tv201.setWanU(bbd.getHandlers());
                }
                tv201.setGetMoney(tv201.getGetMoney().add(bbd.getIncome()));
                tv201.setSendMoney(tv201.getSendMoney().add(bbd.getExpend()).add(bbd.getPoundage()));

            }
            finaList.add(tv201);
        }
        for(Table201VO tv201:finaList){
            tv201.setMargin(tv201.getGetMoney().subtract(tv201.getSendMoney()));
        }
        return finaList;
    }

    @Override
    public List getReportVOList202(Map<String, Object> mapO) {
        List<SeTable> seList = seTableMapper.getAllByTime(mapO);
        //根据时间叠合
        Multimap<String, SeTable> setTMap = ArrayListMultimap.create();
        for (SeTable st : seList) {
            LocalDateTime ct = st.getCreatetime();
            int year = ct.getYear();
            int month = ct.getMonthValue();
            int day = ct.getDayOfMonth();
            int whichT = ct.getHour();
            if (0 < whichT && whichT < 8 || whichT == 0) {
                day = day - 1;
            }
            String dayTS = year + "-" + month + "-" + day;
            setTMap.put(dayTS, st);
        }

        //现在bankByDealtTMap中key为哪一天，value为一天中所有特殊交易list
        Iterator<Map.Entry<String, Collection<SeTable>>> it = setTMap.asMap().entrySet().iterator();
        List<Table201VO> finaList = new ArrayList<>();
        while (it.hasNext()) {
            Map.Entry<String, Collection<SeTable>> entry = it.next();
            //每一天所有的特殊交易的list
            Iterator<SeTable> stList = entry.getValue().iterator();

            while (stList.hasNext()) {
                Table201VO tv201 = Table201VO.builder().time(entry.getKey()).delTpye("").getMoney(BigDecimal.ZERO).sendMoney(BigDecimal.ZERO)
                        .margin(BigDecimal.ZERO).zaoU("").zhongU("").wanU("").build();
                SeTable se = stList.next();
                if (se.getSetype() == 0) {
                    tv201.setDelTpye("内部提现");
                }
                if (se.getSetype() == 1) {
                    tv201.setDelTpye("工作室支出");
                }
                if (se.getSetype() == 2) {
                    tv201.setDelTpye("Q币支出");
                }
                tv201.setSendMoney(se.getSpecialexpend());
                finaList.add(tv201);
            }
        }
        return finaList;
    }

    @Override
    public List getReportVOList3(Map<String, Object> mapO) {
        List<DelAndAccVO> dealLList= dealTableMapper.getAllDAByTime(mapO);
        //根据(时间组合班次)分组
        Multimap<String, DelAndAccVO> dealTMap = ArrayListMultimap.create();
        for(DelAndAccVO daa:dealLList){
            LocalDateTime ct =daa.getCreatetime();
            int year =ct.getYear();
            int month =ct.getMonthValue();
            int day = ct.getDayOfMonth();
            int whichT = ct.getHour();
            if(0<whichT && whichT<8 || whichT == 0){
                day =day-1;
            }
            String dayT = year +"-"+month+"-"+day+"_"+daa.getShift();
            dealTMap.put(dayT,daa);
        }
        Iterator<Map.Entry<String, Collection<DelAndAccVO>>> it = dealTMap.asMap().entrySet().iterator();
        List<Table3VO> finaList = new ArrayList<>();

        while (it.hasNext()) {
            Map.Entry<String, Collection<DelAndAccVO>> entry = it.next();
            //每一天不同班次所有随普通交易list
            Iterator<DelAndAccVO> delList = entry.getValue().iterator();
            //在一个班次中，游戏相同的都叠加了，list.size>0都是不同游戏
            while (delList.hasNext()) {
                BigDecimal zero = BigDecimal.ZERO;
                Table3VO t3v = Table3VO.builder().time(entry.getKey()).shift("").handlers("").remark("").gname("")
                        .sellingscore(zero).giftscore(zero).buyscore(zero).canotscore(zero)
                        .helpscore(zero).helpedname("").worryscore(zero).build();
                DelAndAccVO del = delList.next();
                BeanUtils.copyProperties(del,t3v);
                if(del.getShift() == 0){
                    t3v.setShift("早班");
                }
                if(del.getShift() == 1){
                    t3v.setShift("中班");
                }
                if(del.getShift() == 2){
                    t3v.setShift("晚班");
                }
                List<AccByDea> accByDealtList = del.getAccByDealtList();
                for(AccByDea abd:accByDealtList){
                    t3v.setCanotscore(t3v.getCanotscore().add(abd.getCanotscore()));
                    t3v.setWorryscore(t3v.getWorryscore().add(abd.getWorryscore()));
                }
                finaList.add(t3v);
            }

        }
        //再按照游戏分组，统计一个游戏总的分数变化
        Multimap<String, DelAndAccVO> dealGMap = ArrayListMultimap.create();
        for(DelAndAccVO db:dealLList){
            dealGMap.put(Integer.toString(db.getGid()),db);
        }
        Iterator<Map.Entry<String, Collection<DelAndAccVO>>> itG = dealGMap.asMap().entrySet().iterator();
        while (itG.hasNext()) {
            Map.Entry<String, Collection<DelAndAccVO>> entry = itG.next();
            //同一种游戏，不同天不同班的List
            Iterator<DelAndAccVO> delList = entry.getValue().iterator();
            BigDecimal zero = BigDecimal.ZERO;
            Table3VO t3v = Table3VO.builder().time("按游戏合计").shift("").handlers("").remark("").gname("")
                    .sellingscore(zero).giftscore(zero).buyscore(zero).canotscore(zero)
                    .helpscore(zero).helpedname("").worryscore(zero).build();
            //把同一种游戏list处理完了再add
            while (delList.hasNext()) {
                DelAndAccVO del = delList.next();
                t3v.setGname(del.getGname());
                t3v.setSellingscore(t3v.getSellingscore().add(del.getSellingscore()));
                t3v.setGiftscore(t3v.getGiftscore().add(del.getGiftscore()));
                t3v.setBuyscore(t3v.getBuyscore().add(del.getBuyscore()));
                t3v.setHelpscore(t3v.getHelpscore().add(del.getHelpscore()));
                List<AccByDea> accByDealtList = del.getAccByDealtList();
                for(AccByDea abd:accByDealtList){
                    t3v.setCanotscore(t3v.getCanotscore().add(abd.getCanotscore()));
                    t3v.setWorryscore(t3v.getWorryscore().add(abd.getWorryscore()));
                }
            }
            finaList.add(t3v);
        }
        return finaList;
    }


}
